package com.cd.sendRequest.api.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.cd.common.config.ProjectConfig;
import com.cd.common.constant.Constants;
import com.cd.common.util.AuthUtils;
import com.cd.common.util.DateUtils;
import com.cd.common.util.EnhancedImageResizer;
import com.cd.common.util.file.FileUploadUtils;
import com.cd.sendRequest.GenericCurlExecutor;
import com.cd.sendRequest.api.SendService;
import com.cd.sendRequest.entity.CurlParser;
import com.cd.sendRequest.entity.CurlRequest;
import com.cd.sendRequest.jpa.domain.CURLStore;
import com.cd.sendRequest.jpa.domain.CookieStore;
import com.cd.sendRequest.jpa.domain.DYFollowerActiveData;
import com.cd.sendRequest.jpa.domain.DYResult;
import com.cd.sendRequest.jpa.domain.HomeBanner;
import com.cd.sendRequest.jpa.domain.HomeMenu;
import com.cd.sendRequest.jpa.repo.CURLStoreRepo;
import com.cd.sendRequest.jpa.repo.CookieStoreRepo;
import com.cd.sendRequest.jpa.repo.DYFollowerActiveDataRepo;
import com.cd.sendRequest.jpa.repo.DYResultRepo;
import com.cd.sendRequest.jpa.repo.HomeBannerRepo;
import com.cd.sendRequest.jpa.repo.HomeMenuRepo;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;

@Service
public class SendServiceImpl implements SendService {

    private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SendServiceImpl.class);

    @Autowired
    private DYResultRepo dyResultRepo;

    @Autowired
    private HomeMenuRepo homeMenuRepo;

    @Autowired
    private DYFollowerActiveDataRepo dyFollowerActiveDataRepo;

    @Autowired
    private CookieStoreRepo cookieStoreRepo;

    @Autowired
    private CURLStoreRepo curlStoreRepo;

    @Value("${lqq.environment}")//有没有更性能化一点的加载方式？
    private String environment;

    @Autowired
    private HomeBannerRepo homeBannerRepo;

    @Override
    public void fetCurrentDouyinData() {
        try {
            fetCurrentDYData();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getLocalizedMessage());
        }
    }

    @Override
    public List<DYResult> getDateDouyinData(String date, String userId) {
        //查询指定月的抖音粉丝数据
        return dyResultRepo.findAllByDateAndUserId(date, userId);
    }

    @Override
    public void addHomeMenu(HomeMenu homeMenu) {
        Long userId = AuthUtils.currentUserId();
        if (homeMenu.getUserId() == null) {
            homeMenu.setUserId(userId);
        } else if (homeMenu.getUserId() != userId) {
            throw new RuntimeException("禁止操作他人菜单");
        }
        homeMenuRepo.save(homeMenu);
    }

    @Override
    public List<HomeMenu> getAllHomeMenuByUserId() {
        Long userId = AuthUtils.currentUserId();
        List<HomeMenu> homeMenus = homeMenuRepo.findByUserIdAndIsDeletedFalse(userId);
        return homeMenus;
    }

    @Override
    public void deletedHomeMenu(Long menuId) {
        HomeMenu homeMenu = homeMenuRepo.findById(menuId).orElse(null);
        if (homeMenu.getUserId() != AuthUtils.currentUserId()) {
            throw new RuntimeException("禁止操作他人菜单");
        }
        if (homeMenu != null) {
            homeMenu.setIsDeleted(true);
            homeMenuRepo.save(homeMenu);
        }
    }

    @Override
    public Integer getYunFollowerData(Integer count) throws Exception {
        // ✅ 使用完整的 URL（来自 curl）
        String urlString = "https://creator.douyin.com/aweme/v1/creator/relation/follower/list/" +
                "?aid=2906" +
                "&app_name=aweme_creator_platform" +
                "&device_platform=web" +
                "&referer=https%3A%2F%2Fcreator.douyin.com%2F" +
                "&user_agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+WOW64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F94.0.4606.71+Safari%2F537.36+Core%2F1.94.191.400+QQBrowser%2F11.5.5245.400" +
                "&cookie_enabled=true" +
                "&screen_width=1920" +
                "&screen_height=1080" +
                "&browser_language=zh-CN" +
                "&browser_platform=Win32" +
                "&browser_name=Mozilla" +
                "&browser_version=5.0+%28Windows+NT+10.0%3B+WOW64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F94.0.4606.71+Safari%2F537.36+Core%2F1.94.191.400+QQBrowser%2F11.5.5245.400" +
                "&browser_online=true" +
                "&timezone_name=Asia%2FShanghai" +
                "&cursor=0" +
                "&sortType=score" +
                "&orderBy=1" +
                "&count=20";
        //"&msToken=CRlbXYVDiKo20-JJAhXd0ThM65tCfLQ8b4W_KGYYuyVt_lIecb4ZNCPN0eUVZmoXyvQG_vOeymWB8whO4fgM3cBQPhseNKCtExzn2jJLGrO3MhMMaO9o4qaqyrVG9v2DKNdVXykdjqmJ76UZDVNY_StPGAyNdWW_UyUcvKtrALndP4DeAYnu" +
        //"&a_bogus=DfUfkzXJEqQnOpFSucB87X%2FU4qjArTWyVFTxWTtn7Ookc7eGUqHeLacRbow%2FcsNZsYMVh6q7oEMANExc0skhZZVkwmkDu0sjPzQV9w8Lg17hY-iZ7H8wSkbEoiTb0CsY%2FQ5IEBiXA0Fy2gc3hqnklV-GS5FOQQmDbNqyd2sca9WnVSEHI9dUeBbdwhUc";

        urlString = urlString.replace("&cursor=0", "&cursor=" + count);
        URL url = new URL(urlString);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        // ✅ 设置请求方法
        conn.setRequestMethod("GET");

        // ✅ 设置超时（防止卡死）
        conn.setConnectTimeout(10000);
        conn.setReadTimeout(15000);

        // ✅ 允许重定向（等价于 curl --location）
        conn.setInstanceFollowRedirects(true);

        // ✅ 添加 Headers（完全复制 curl）
        conn.setRequestProperty("authority", "creator.douyin.com");
        conn.setRequestProperty("sec-ch-ua", "\";Not A Brand\";v=\"99\", \"Chromium\";v=\"94\"");
        conn.setRequestProperty("accept", "application/json, text/plain, */*");
        //conn.setRequestProperty("x-secsdk-csrf-token", "0001000000012893a606ea78857eb8dd8b5e8269367eea3a8d14177c15aa3e8e206269219b4d186d0a5ac5e3c815");
        conn.setRequestProperty("sec-ch-ua-mobile", "?0");
        conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.191.400 QQBrowser/11.5.5245.400");
        conn.setRequestProperty("sec-ch-ua-platform", "\"Windows\"");
        conn.setRequestProperty("sec-fetch-site", "same-origin");
        conn.setRequestProperty("sec-fetch-mode", "cors");
        conn.setRequestProperty("sec-fetch-dest", "empty");
        conn.setRequestProperty("referer", "https://creator.douyin.com/creator-micro/data/following/follower");
        conn.setRequestProperty("accept-language", "zh-CN,zh;q=0.9");

        // ✅ Cookie（确保完整）
        Long userId = AuthUtils.currentUserId();
        //查询该用户的cookie
        CookieStore cookieStore = cookieStoreRepo.findByOwnerIdAndPlatformAndUsageType(userId, Constants.DOUYIN, Constants.FOLLOWER_ACTIVE).get();
        conn.setRequestProperty("cookie", cookieStore.getCookie());
        //conn.setRequestProperty("cookie", "");
        //jiaoxin
        //conn.setRequestProperty("cookie", "UIFID_TEMP=f718f562fcd874811d9c30568517194c189689a7c74491d0ed9c7c2e831358f1fb3a6a11b7ae03b8ac6faddb49720b6e586113278d5b00c0ded88887049970ab662426b3ca2a21845c2ca03d63fbfa62; hevc_supported=true; SelfTabRedDotControl=%5B%5D; SEARCH_RESULT_LIST_TYPE=%22single%22; passport_csrf_token=cba54adeea3874abd7c2694fd8846465; passport_csrf_token_default=cba54adeea3874abd7c2694fd8846465; __security_mc_1_s_sdk_crypt_sdk=37a4fa90-4b53-8d8f; passport_assist_user=CkHIhJJzIEDs8GI_KqVNo9gThens8R_WVGktyeLPfcBJbJim2o_xKX0dbGU0wqrN1HPuyW1wzpwoTh8p8JGGJKbjhRpKCjwAAAAAAAAAAAAAT5MVNRGJ2_71t0KZBd3SFM-xQCYJooAsFFsK8SXrAxKW0DS8aqiWm4fqsXM4Pz4G6LQQlLn-DRiJr9ZUIAEiAQNJG9yM; sid_guard=796bde0c99a0a1b00292c819ebc83b6a%7C1760083022%7C5184000%7CTue%2C+09-Dec-2025+07%3A57%3A02+GMT; uid_tt=cee81e7a4418c651270137486ca583c1; uid_tt_ss=cee81e7a4418c651270137486ca583c1; sid_tt=796bde0c99a0a1b00292c819ebc83b6a; sessionid=796bde0c99a0a1b00292c819ebc83b6a; sessionid_ss=796bde0c99a0a1b00292c819ebc83b6a; session_tlb_tag=sttt%7C16%7CeWveDJmgobACksgZ68g7av________-nznBYn1stHIXLb-fYZr1MCSwg1NeGLLiqjO6VFRQ3idY%3D; is_staff_user=false; sid_ucp_v1=1.0.0-KDE3MWExYTMyZTdlMGM0MTk0ZTY4NDY1NGFmM2UyMDcwMmNlMzZhM2UKIQjc9ZGz6qywAxDO-KLHBhjaFiAMMNLMqcMGOAdA9AdIBBoCbGYiIDc5NmJkZTBjOTlhMGExYjAwMjkyYzgxOWViYzgzYjZh; ssid_ucp_v1=1.0.0-KDE3MWExYTMyZTdlMGM0MTk0ZTY4NDY1NGFmM2UyMDcwMmNlMzZhM2UKIQjc9ZGz6qywAxDO-KLHBhjaFiAMMNLMqcMGOAdA9AdIBBoCbGYiIDc5NmJkZTBjOTlhMGExYjAwMjkyYzgxOWViYzgzYjZh; _bd_ticket_crypt_doamin=2; __security_mc_1_s_sdk_sign_data_key_web_protect=6b79f97a-44c9-8d5f; __security_mc_1_s_sdk_cert_key=7f61b2ba-4791-900a; __security_server_data_status=1; x-web-secsdk-uid=10d721ab-caf0-4bd2-83a3-36d8488af82e; gfkadpd=2906,33638; _tea_utm_cache_2906=undefined; csrf_session_id=1f1ffd6d0ce1e2e61caa2622f3beff5a; gd_random=eyJtYXRjaCI6dHJ1ZSwicGVyY2VudCI6MC4yMDg5NzYxMDE2Mjc4MTUzMn0=.tktlpXGJ+2+87vxRJKslxunVYXsu2MNlXXt14M9UVF4=; ttwid=1%7Co1jMt67v_odqYgUHrcwC5hAdw96oWU8W7L4JSjIH6Lc%7C1761034816%7C2416e880fb319befbbff1ad8e49d33aea69ce2e314f544b1ec8441f61e7c7496; bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcmVlLXB1YmxpYy1rZXkiOiJCREJkYklMNHBLSlAxdWdKWGpORFQ3TXRBc2pYSFFBUWNIekZQWXdNZkJueER4WHpLcm1vUUlSUjFoYlB6ejUyS3lxaWxmREg4VjBqeWJtK05udlJoYXc9IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoyfQ%3D%3D; passport_fe_beating_status=true; odin_tt=34643e69748d865ad70beffec0c27805462d8a28eaae9976347805248581e5acbc78f798fc103b0fc9c2b25588957cee0acba11e0e527126835869f9ad804be9; bd_ticket_guard_client_data_v2=eyJyZWVfcHVibGljX2tleSI6IkJEQmRiSUw0cEtKUDF1Z0pYak5EVDdNdEFzalhIUUFRY0h6RlBZd01mQm54RHhYektybW9RSVJSMWhiUHp6NTJLeXFpbGZESDhWMGp5Ym0rTm52Umhhdz0iLCJ0c19zaWduIjoidHMuMi45ZWU2MGU0ZGMyZTUxNDE2NzdjNDYzZWQwZDE4MWM5MWU3ZDI2ZjhjMjFmZDljZDIxNWI0ZTk0OWIxMDg1MDA4YzRmYmU4N2QyMzE5Y2YwNTMxODYyNGNlZGExNDkxMWNhNDA2ZGVkYmViZWRkYjJlMzBmY2U4ZDRmYTAyNTc1ZCIsInJlcV9jb250ZW50Ijoic2VjX3RzIiwicmVxX3NpZ24iOiJxSzVQWGdwTm4rb2N5RzlrZnRkZDFXcXg4WFZLdzlZVmN4eUw0d0MrUDBNPSIsInNlY190cyI6IiNMTHpacEJwVkN6dE5TaFZ4MmtTSWk5dU1uSVNSWWhhMjRSRExma0hFcmhhNmRZM3J6eTN1Y0k0OEVKWVkifQ%3D%3D");

        // ✅ 启用 gzip（curl 默认支持，我们也支持）
        conn.setRequestProperty("Accept-Encoding", "gzip");

        // ✅ 连接
        conn.connect();

        // ✅ 获取响应码
        int responseCode = conn.getResponseCode();
        System.out.println("Response Code: " + responseCode);

        // ✅ 判断输入流来源
        InputStream inputStream = (responseCode == HttpURLConnection.HTTP_OK) ?
                conn.getInputStream() : conn.getErrorStream();

        // ✅ 检查是否是 gzip 压缩
        String contentEncoding = conn.getContentEncoding();
        if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) {
            inputStream = new GZIPInputStream(inputStream);
        }

        // ✅ 使用 UTF-8 读取文本
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(inputStream, StandardCharsets.UTF_8)
        );

        StringBuilder response = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            response.append(line).append("\n");
        }
        reader.close();
        inputStream.close();
        conn.disconnect();
        logger.info("第{}组返回报文为=>[{}]", count / 20, response.toString());
        // 解析整个 JSON
        JSONObject jsonObject = JSON.parseObject(response.toString());

        List<DYFollowerActiveData> dyFollowerActiveDataList =
                JSON.parseObject(jsonObject.getString("user_info_list"), new TypeReference<List<DYFollowerActiveData>>() {
                });
        //为空直接返回
        if (dyFollowerActiveDataList == null) {
            return 0;
        }
        //添加其他信息
        if (dyFollowerActiveDataList.size() != 0) {
            dyFollowerActiveDataList.forEach(dyFollowerActiveData -> {
                dyFollowerActiveData.setRecordTime(DateUtils.getDate());
                dyFollowerActiveData.setOwner(cookieStore.getUsername());
                dyFollowerActiveData.setOwnerId(userId);
                //优化首页访问 不需要登录 登录在另外的链接
                //获取粉丝列表 比对
            });
            dyFollowerActiveDataRepo.saveAll(dyFollowerActiveDataList);
        }
        return dyFollowerActiveDataList.size();
    }

    @Override
    public String getAllYunFollowerData() {
        //todo 到时候重构吧 需要userId和cookie 考虑里面取还是传参 具体怎么拿
        try {
            for (int i = 0; i < 25; i++) {//最多获取前五百个 第26组会为空
                Integer yunFollowerData = getYunFollowerData(i * 20);
                if (yunFollowerData == 0) {
                    logger.info("获取粉丝活跃度数据结束,本次获取{}个", yunFollowerData);
                    break;
                }
            }
        } catch (Exception e) {
            logger.error("获取粉丝活跃度数据失败", e);
            e.printStackTrace();
            return "获取失败";
        }

        return "获取成功";
    }

    @Override
    public String executeAll() throws Exception {
        List<CURLStore> list = curlStoreRepo.findByIsExecute(1);
        for (CURLStore curlStore : list) {
            String curlCommand = curlStore.getCurl();
            CurlParser parser = new CurlParser();
            CurlRequest request = parser.parse(curlCommand);
            String responseData = sendRequest(request);// 发送请求
            if (curlStore.getName().equals("粉丝数拉取")) {
                parseDYFollowerData(responseData, curlStore.getOwnerId());
            }
            logger.info("return data => {}", responseData);
        }
        return null;
    }

    @Override
    public void upload(MultipartFile file, String type) throws Exception {
        //基础路径
        String fileName = file.getOriginalFilename();
        //文件编号
        Integer maxOrderByType = homeBannerRepo.findMaxOrderByType(type);
        HomeBanner homeBanner = new HomeBanner();
        homeBanner.setDescription("");
        if (maxOrderByType == null) {
            homeBanner.setOrder(1);
        } else {
            homeBanner.setOrder(maxOrderByType + 1);
        }
        homeBanner.setType(type);

        String currentJpgDir = ProjectConfig.getProfile();
        currentJpgDir = currentJpgDir
                .concat(File.separator)
                .concat("jpg")
                .concat(File.separator)
                .concat("raw");

        String s = FileUploadUtils.uploadNoDate(currentJpgDir, file);
        currentJpgDir = currentJpgDir.concat(File.separator).concat(fileName);
        String targetDir = currentJpgDir
                .replace("raw", "show")//替换目标路径名
                //.replace(file.getOriginalFilename().split("\\.")[0], type + "-" + homeBanner.getOrder());//替换目标文件名
                .replace(file.getOriginalFilename(), type + "-" + homeBanner.getOrder()+".jpg");//替换目标文件名
        //error 如果文件有两个. 实际使用可能会报错
        //指定位置读取文件 转换
        EnhancedImageResizer.resizeImage(currentJpgDir, targetDir, 600, 400, 1f);

        //写入数据库

        homeBanner.setImgPath(targetDir.replace(ProjectConfig.getProfile(), "/profile"));
        homeBannerRepo.save(homeBanner);
    }

    private void parseDYFollowerData(String json, Long userId) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode rootNode = mapper.readTree(json);

        // 获取 metrics 数组
        JsonNode metrics = rootNode.get("metrics");

        List<DYResult> fanTrends = new ArrayList<>();

        // 遍历 metrics，找到 metric_name 为 "总粉丝量" 的项
        for (JsonNode metric : metrics) {
            if ("总粉丝量".equals(metric.get("metric_name").asText())) {
                JsonNode trends = metric.get("trends");
                for (JsonNode trend : trends) {
                    DYResult dyResult = new DYResult();
                    dyResult.setFollowerCount(trend.get("value").asLong());
                    dyResult.setRecordTime(covertDYTimeToDate(trend.get("date_time").asText()));
                    dyResult.setUserId(userId.toString());
                    dyResult.setCreateTime(new Date());
                    fanTrends.add(dyResult);
                }
                break; // 找到即可退出
            }
        }
        logger.info("获取数据成功，本次数据为: {}", fanTrends);
        //save 提取数据库中最大的日期 然后用stream过滤出大于这个的 剩下的插入
        List<DYResult> byUserId = dyResultRepo.findByUserId(userId.toString());
        //选出日期最大的数据
        int maxTime = 0;
        for (DYResult dyResult : byUserId) {
            int currentTime = convertTimeStringToInt(dyResult.getRecordTime());
            if (currentTime > maxTime) maxTime = currentTime;
        }
        logger.info("当前最大时间为{}", maxTime);
        int finalMaxTime = maxTime;
        List<DYResult> collect = fanTrends.stream().filter(data ->
                convertTimeStringToInt(data.getRecordTime()) > finalMaxTime
        ).collect(Collectors.toList());

        logger.info("本次处理{}条数据，：{}", collect.size(), collect);
        dyResultRepo.saveAll(collect);

    }

    private int convertTimeStringToInt(String recordTime) {
        recordTime = recordTime.replace("-", "");
        return Integer.parseInt(recordTime);
    }

    private String covertDYTimeToDate(String date_time) {
        //20250101转换为2025-01-01
        return date_time.substring(0, 4) + "-" + date_time.substring(4, 6) + "-" + date_time.substring(6, 8);
    }

    /**
     * @Description 获取数据接口
     * @Author lqq
     * @Date 2025/8/24 14:03
     **/
    private void fetCurrentDYData() throws UnsupportedEncodingException {
        // 所有查询参数（原始 curl 中的 query string）
        StringBuilder queryString = new StringBuilder();
        queryString.append("device_platform=webapp");
        queryString.append("&aid=6383");
        queryString.append("&channel=channel_pc_web");
        queryString.append("&publish_video_strategy_type=2");
        queryString.append("&source=channel_pc_web");
        queryString.append("&sec_user_id=MS4wLjABAAAAvkWRPQg5BLmr9BBQpmyF32JkSlHR6xDbJfDiYuW9i9c");
        queryString.append("&personal_center_strategy=1");
        queryString.append("&profile_other_record_enable=1");
        queryString.append("&land_to=1");
        queryString.append("&update_version_code=170400");
        queryString.append("&pc_client_type=1");
        queryString.append("&pc_libra_divert=Windows");
        queryString.append("&support_h265=0");
        queryString.append("&support_dash=0");
        queryString.append("&cpu_core_num=8");
        queryString.append("&version_code=170400");
        queryString.append("&version_name=17.4.0");
        queryString.append("&cookie_enabled=true");
        queryString.append("&screen_width=1920");
        queryString.append("&screen_height=1080");
        queryString.append("&browser_language=zh-CN");
        queryString.append("&browser_platform=Win32");
        queryString.append("&browser_name=QQBrowser");
        queryString.append("&browser_version=11.5.5245.400");
        queryString.append("&browser_online=true");
        queryString.append("&engine_name=Blink");
        queryString.append("&engine_version=94.0.4606.71");
        queryString.append("&os_name=Windows");
        queryString.append("&os_version=10");
        queryString.append("&device_memory=8");
        queryString.append("&platform=PC");
        queryString.append("&downlink=10");
        queryString.append("&effective_type=4g");
        queryString.append("&round_trip_time=200");
        queryString.append("&webid=7542330266888734234");
        queryString.append("&uifid=").append(URLEncoder.encode("b2583564a92000c9b3dd51f97c6c25584aafe39bdaa6022d5844eca47904ba35de8cde1aaa0ff5af6cc24b750742499fa4f3d908d707f92ba05f08e13ff150eebbd94da375442ce87d7b70f79c8ccdc8a6118df78ce977e7a6209720b935466f1033977ff8db2a9c863d193b63664e63c003ee74501c4aaf71d467d1ee58dc196ea7a99a332acff3ee7a9b89354ca598e3ef795d533333399a7ff703a66fa131aa6ed3f84156390472a9b09f98534d67f35513220b961974cf7ec840101eb84f", "UTF-8"));
        queryString.append("&msToken=0GXJE25S2peIhBGHdPYPo7qgWRKt4XOkyT7KBhN51IKXBPt06TGkYz5e7gia1JsKF7tpHSmpD2NnhOzeNg3CuIsW2DbJUnElZOFpIu9cR0ypooxbGcbYBLjR92U02Db4y-yjiGI0nwLOj0C0-_PoUiaHJgs7FquOwmp3TIRkpBY7mdlFtTBcdw%3D%3D");
        queryString.append("&a_bogus=xfUVDzXjxdRbcVFG8OcE7C3UKlVlrT8yHBi2SElT7NzMcqzY6mPfgaeCJxFb4zbEs8Bhk9V7Sf0Abddc0UXhZ9npwmpDudzbMsQ9nu6oZHkgbTvgJN8pebtEuiPTUSGYQA2rEpwXW0zL2253iqnkl5-aH5FO5QmDSrqyd2mcj9WxVAEHIxdXtpGWFwL%3D");
        queryString.append("&verifyFp=verify_meqg1hnz_Fg4G4pG9_tJWM_4Aos_A3XU_S23DceGVPsmc");
        queryString.append("&fp=verify_meqg1hnz_Fg4G4pG9_tJWM_4Aos_A3XU_S23DceGVPsmc");

        String url = "https://www.douyin.com/aweme/v1/web/user/profile/other/?" + queryString;

        // 创建 HttpClient
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {

            // 创建 GET 请求
            HttpGet httpGet = new HttpGet(url);

            // 添加所有请求头（完全复制 curl -H）
            httpGet.setHeader("authority", "www.douyin.com");
            httpGet.setHeader("sec-ch-ua", "\";Not A Brand\";v=\"99\", \"Chromium\";v=\"94\"");
            httpGet.setHeader("accept", "application/json, text/plain, */*");
            httpGet.setHeader("uifid", "b2583564a92000c9b3dd51f97c6c25584aafe39bdaa6022d5844eca47904ba35de8cde1aaa0ff5af6cc24b750742499fa4f3d908d707f92ba05f08e13ff150eebbd94da375442ce87d7b70f79c8ccdc8a6118df78ce977e7a6209720b935466f1033977ff8db2a9c863d193b63664e63c003ee74501c4aaf71d467d1ee58dc196ea7a99a332acff3ee7a9b89354ca598e3ef795d533333399a7ff703a66fa131aa6ed3f84156390472a9b09f98534d67f35513220b961974cf7ec840101eb84f");
            httpGet.setHeader("sec-ch-ua-mobile", "?0");
            httpGet.setHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.191.400 QQBrowser/11.5.5245.400");
            httpGet.setHeader("sec-ch-ua-platform", "\"Windows\"");
            httpGet.setHeader("sec-fetch-site", "same-origin");
            httpGet.setHeader("sec-fetch-mode", "cors");
            httpGet.setHeader("sec-fetch-dest", "empty");
            httpGet.setHeader("referer", "https://www.douyin.com/user/MS4wLjABAAAAvkWRPQg5BLmr9BBQpmyF32JkSlHR6xDbJfDiYuW9i9c?from_tab_name=main");
            httpGet.setHeader("accept-language", "zh-CN,zh;q=0.9");

            // Cookie（必须完整）
            String cookie = "UIFID_TEMP=b2583564a92000c9b3dd51f97c6c25584aafe39bdaa6022d5844eca47904ba35de8cde1aaa0ff5af6cc24b750742499fa4f3d908d707f92ba05f08e13ff150eeba2c9a7ee3952d03c3e50a9df9c0c3d0bd74f30b0048686dbe2ca0b684b0eb36c88ccbc2846262a0cc09746210ee572f; "
                    + "UIFID=b2583564a92000c9b3dd51f97c6c25584aafe39bdaa6022d5844eca47904ba35de8cde1aaa0ff5af6cc24b750742499fa4f3d908d707f92ba05f08e13ff150eebbd94da375442ce87d7b70f79c8ccdc8a6118df78ce977e7a6209720b935466f1033977ff8db2a9c863d193b63664e63c003ee74501c4aaf71d467d1ee58dc196ea7a99a332acff3ee7a9b89354ca598e3ef795d533333399a7ff703a66fa131aa6ed3f84156390472a9b09f98534d67f35513220b961974cf7ec840101eb84f; "
                    + "odin_tt=2bd2537ba59e3f89e6af5bf818e7c736c692380722b5d414da07ae2a29b117736c6ea70284c93f69ef5a4f833c2a69d4b5915d8b3078a3fb8ec848af33917355b0a4b9ba030bae22aeaad036665a8ebe; "
                    + "volume_info=%7B%22isUserMute%22%3Afalse%2C%22isMute%22%3Atrue%2C%22volume%22%3A0.01%7D; "
                    + "enter_pc_once=1; "
                    + "x-web-secsdk-uid=8f156aeb-f025-471c-a589-c825af2b3cee; "
                    + "s_v_web_id=verify_meqg1hnz_Fg4G4pG9_tJWM_4Aos_A3XU_S23DceGVPsmc; "
                    + "douyin.com; "
                    + "device_web_cpu_core=8; "
                    + "device_web_memory_size=8; "
                    + "architecture=amd64; "
                    + "dy_sheight=1080; "
                    + "dy_swidth=1920; "
                    + "strategyABtestKey=%221756085630.728%22; "
                    + "passport_csrf_token=7c1dd37b3b424dcfe8fafb943d80130b; "
                    + "passport_csrf_token_default=7c1dd37b3b424dcfe8fafb943d80130b; "
                    + "fpk1=U2FsdGVkX18576tij8kASu8mGrqklesg1WUvsW5bG9N+sYLec5eQimOZRG462AoX2inCRmLq4pgHgXyklm0zmg==; "
                    + "fpk2=9396ff1a21fb53d3bff9ce4dda5d111e; "
                    + "__security_mc_1_s_sdk_crypt_sdk=8f365f2d-45f3-a3e8; "
                    + "bd_ticket_guard_client_web_domain=2; "
                    + "gulu_source_res=eyJwX2luIjoiZTJjZDdjNTBmY2Y3NTdlZjBmYWZiMzg2MmE1NGU4NDk2N2E0NjA0MzU0ODZjMjcwYzk4YWYyNTQ3ZjFiN2IxNCJ9; "
                    + "bit_env=JOnShWx0PRZ6bwWENFllM_zRCX_V_DB-5SKYpeR0DL3q4aeExDVAluAYsjP_30K76QPnOlvLOO8x0Dj7SUCbzFsYO-xR4sWwgbFNPEee2Gfkh0fNK-XWyJQzah1e0AMlCsFs9DDZ2QUO4j9egBatisUUajerprGfsjU4XaKIm8nxPGpyGMU9J1UnvsW_E3CsaPaGpH6939sR32mLdaI7MGYIf_LJWBBPiM_v5QSyTROxQqQS6D5vXFcqu_Xzoz9DCKGn7kxIDVetShSAPy77v_KxuPCEqnI7r-Q2Ah4ZzI6ofrqbo-yKYa4hqT5t74HeHatEdLWD6Un-bgJ24NJ-mL7Le0OpGP0uUlHx7m2JCr5zQSoRHIR_LIePfijYn6snssQic5pK9RSQ_ktfiLFqWvfWHbJc2C7Vv_OOWJL5cD6tuLWmYfAxGE8odzaApiCPEZArdJC66treVHmuwEA-rKgr6Hi6v550WhE-bdbBifdaH-67I87qNzGdbon25uS_lyy-ZJvtkNGIDtqgXBPyNOnZV4TlBqFf05J1Kjs5eUP7osfZaz9TEktneaqBm-LKRPWIkZTzkg9Th-OvECzafg%3D%3D; "
                    + "sdk_source_info=7e276470716a68645a606960273f276364697660272927676c715a6d6069756077273f276364697660272927666d776a68605a607d71606b766c6a6b5a7666776c7571273f275e58272927666a6b766a68605a696c6061273f27636469766027292762696f64695a7364776c6467696076273f275e582729277672715a646971273f2763646976602729277f6b5a666475273f2763646976602729276d6a6e5a6b60766c6a6b273f2763646976602729276c6b6f5a7f6367273f27636469766027292771273f27373337363133303d3533303234272927676c715a75776a716a666a69273f2763646976602778; "
                    + "passport_auth_mix_state=mbgrjjgzor0fxhg3awfyayu8q81o6yzw70nc6pe6asmrmtu1; "
                    + "stream_player_status_params=%22%7B%5C%22is_auto_play%5C%22%3A0%2C%5C%22is_full_screen%5C%22%3A0%2C%5C%22is_full_webscreen%5C%22%3A0%2C%5C%22is_mute%5C%22%3A1%2C%5C%22is_speed%5C%22%3A1%2C%5C%22is_visible%5C%22%3A0%7D%22; "
                    + "__ac_nonce=068abbda8008cd0e41f7d; "
                    + "__ac_signature=_02B4Z6wo00f01X5h-bwAAIDB.mMD.a2GfNV-Qf0AADc386; "
                    + "home_can_add_dy_2_desktop=%220%22; "
                    + "ttwid=1%7CVLqDQp6iYmCExz_KeUp0VlBMPl2lHxs-7BBVYNn11_8%7C1756085679%7C4dbb7b1be8c8116bde52a0ec370928dfe1aee86061e61be41df3f2c0e601eece; "
                    + "bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcGFnZS1wdWJsaWMta2V5IjoiQlBYb3NSRm1QV0VXNkhZMC85WlhaUjNLeXpTd1RYRG0zK3p2ZDVydlNMVFZFM09NNW5sTDRpSWJGZkFOVnZLUVVpWUt5cTBoSURjcEtOeitTV2xtdHZyRzA9IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoyfQ%3D%3D; "
                    + "download_guide=%222%2F20250825%2F0%22; "
                    + "WallpaperGuide=%7B%22showTime%22%3A1756085849799%2C%22closeTime%22%3A0%2C%22showCount%22%3A1%2C%22cursor1%22%3A10%2C%22cursor2%22%3A2%7D; "
                    + "IsDouyinActive=true; "
                    + "stream_recommend_feed_params=%22%7B%5C%22cookie_enabled%5C%22%3Atrue%2C%5C%22screen_width%5C%22%3A1920%2C%5C%22screen_height%5C%22%3A1080%2C%5C%22browser_online%5C%22%3Atrue%2C%5C%22cpu_core_num%5C%22%3A8%2C%5C%22device_memory%5C%22%3A8%2C%5C%22downlink%5C%22%3A10%2C%5C%22effective_type%5C%22%3A%5C%224g%5C%22%2C%5C%22round_trip_time%5C%22%3A200%7D%22; "
                    + "biz_trace_id=953e0f3b";

            httpGet.setHeader("cookie", cookie);

            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                logger.info("Status Code: " + response.getCode());

                // 获取响应体
                String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
                logger.info("Response Body: " + responseBody);

                // 提取 max_follower_count
                extractMaxFollowerCount(responseBody);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 简单提取 max_follower_count（生产环境建议用 JSON 库）
    private void extractMaxFollowerCount(String json) {
        String key = "\"max_follower_count\":";
        int index = json.indexOf(key);
        if (index != -1) {
            index += key.length();
            int endIndex = json.indexOf(",", index);
            if (endIndex == -1) endIndex = json.indexOf("}", index);
            String value = json.substring(index, endIndex).trim();
            try {
                long count = Long.parseLong(value);
                logger.info(" user.max_follower_count: " + count);
                DYResult result = new DYResult();
                //result.setUserId();
                result.setCreateTime(new Date());
                result.setRecordTime(DateUtils.getDate());
                result.setFollowerCount(count);
                dyResultRepo.save(result);
            } catch (NumberFormatException e) {
                logger.error("解析 max_follower_count 错误: " + value);
            }
        } else {
            logger.warn("字段 'max_follower_count' 未找到");
        }
    }

    private static String sendRequest(CurlRequest request) {
        logger.info("开始发送请求...，request is {}", request.toString());
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpUriRequestBase post = null;
            if (!request.getMethod().equals("GET")) {
                logger.info("该请求为get");
                post = new HttpGet(request.getUrl());
            } else {
                post = new HttpPost(request.getUrl());
            }
            // 设置 headers
            for (Map.Entry<String, String> entry : request.getHeaders().entrySet()) {
                if (!entry.getKey().equals("Content-Length")) {
                    post.setHeader(entry.getKey(), entry.getValue());
                }
            }
//            if (request.getBody()!=null && request.getBody().length()>0) {//手动设置length排除长度
//                //post.setHeader("Content-Length",request.getBody().length());
//                //logger.info("length is {}",request.getBody().length());
//                System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
//                System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire", "DEBUG");
//                //post.setEntity(request.getBody().getBytes(StandardCharsets.UTF_8), ContentType.APPLICATION_JSON);
//            }
            //ClassicHttpResponse response = httpClient.executeOpen(null, post, null);
            if (request.getBody() != null && request.getBody().length() > 0) {
                post.setEntity(new StringEntity(request.getBody(), ContentType.APPLICATION_JSON));
            }
            CloseableHttpResponse response = httpClient.execute(post);
            logger.info("Status Code: " + response.getCode());
            if (response.getEntity() != null) {
                String body = null;
                try {
                    body = EntityUtils.toString(response.getEntity());
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
                //logger.info("Response Body: " + body);
                return body;
            }

        } catch (IOException e) {
            logger.error("请求失败: " + e.getMessage());
            e.printStackTrace();
        }
        return null;
    }
}
